<template>
  <div>
    <el-upload
        :action="uploadUrl"
        :on-preview="handlePreview"
        :on-remove="handleRemove"
        :before-remove="beforeRemove"
        :limit="props.limit"
        :on-exceed="handleExceed"
        :http-request="customHttpRequest"
        :file-list="props.fileList"
        :multiple="props.multiple"
        v-bind="$attrs"
    >
      <el-button type="primary">选择文件</el-button>
    </el-upload>
  </div>
</template>

<script setup>
import {ref} from 'vue';
import {uploadSingleFile, downloadFile} from '@/utils/fileService.js';
import {ElMessageBox} from "element-plus";

// 定义 props
const props = defineProps({
  limit: {
    type: Number,
    default: 1, // 默认限制上传一个文件
  },
  multiple: {
    type: Boolean,
    default: false, // 默认不允许上传多个文件
  },
  replaceOnExceed: {
    type: Boolean,
    default: true, // 默认超出限制时不替换文件
  },
});

// 定义 emit
const emit = defineEmits(['file-uploaded', 'file-removed', 'file-success-multipartFile']);

// 获取上传 URL
const uploadUrl = `${import.meta.env.VITE_APP_BASE_API}/common/upload`;

// 文件列表
const fileList = ref([]);

// 自定义上传请求
const customHttpRequest = async (options) => {
  const file = options.file;
  try {
    const multipartFile = {
      name: file.name, // 文件名
      originalFilename: file.name, // 原始文件名
      contentType: file.type, // 文件类型
      size: file.size, // 文件大小
      file: file, // 原始文件对象
    };
    const uploadRes = await uploadSingleFile(file); // 调用通用上传接口并带上 token
    console.log('文件上传成功:', uploadRes);
    emit('file-uploaded', uploadRes); // 通知父组件文件已上传
    emit('file-success-multipartFile', multipartFile);
  } catch (err) {
    console.error('上传失败:', err);
  }
};

// 预览文件
const handlePreview = async (file) => {
  console.log('预览文件:', file);
  try {
    await downloadFile(file.name); // 调用下载文件方法来预览文件
  } catch (err) {
    console.error('预览失败:', err);
  }
};

// 移除文件
const handleRemove = (file, fileList) => {
  console.log('移除文件:', file, fileList);
  emit('file-removed', file); // 通知父组件文件已移除
};

// 确认移除文件
const beforeRemove = (file, fileList) => {
  return new Promise((resolve, reject) => {
    ElMessageBox.confirm(`确定移除 ${file.name}？`).then(() => {
      resolve();
    }).catch(() => {
      reject();
    });
  });
};

// 超出文件限制
const handleExceed = async (files, fileList) => {
  if (props.replaceOnExceed) {
    console.log('超出文件限制，替换上一个文件');
    fileList.splice(0, 1); // 移除第一个文件
    fileList.push(files[0]); // 添加新文件
    emit('file-uploaded', files[0]); // 通知父组件文件已上传
    const file = files[0];
    try {
      const uploadRes = await uploadSingleFile(file); // 调用通用上传接口并带上 token
      console.log('文件上传成功:', uploadRes);
      emit('file-uploaded', uploadRes); // 通知父组件文件已上传
    } catch (err) {
      console.error('上传失败:', err);
    }
  } else {
    console.log('超出文件限制，提示用户');
    ElMessageBox.alert('超出文件限制，请先移除一个文件后再上传。', '提示', {
      confirmButtonText: '确定',
      type: 'warning',
    });
  }
};
</script>

<style scoped>
/* 样式可以根据需要自定义 */
</style>
